package br.indt.framework.scheduler;

import java.util.Vector;

/**
 * PriorityQueue:
 *     Ordered in Crescent Order.
 *     Elements already stored are ignored
 * 
 * @author efirmino
 */
public class PriorityQueue {
   Vector queue;

   public PriorityQueue() {
       queue = new Vector();
   }

   public PriorityQueue(int initialCapacity) {
       queue = new Vector(initialCapacity);
   }

   public void add(Object element, int priority) {
       Item item = new Item(element, priority);
       insertItemByPriority(item);
   }

   public void remove(int index) {
       queue.removeElementAt(index);
   }

   public void remove(Object element) {
       int length = queue.size();
       for (int i = 0; i < length; i++) {
           Item indexItem = (Item) queue.elementAt(i);
           if (element == indexItem.getElement()) {
               queue.removeElementAt(i);
               break;
           }
       }
   }

   public void removeAll() {
       queue.removeAllElements();
   }

   public Object get(int index) {
       if (index < size()) {
           return ((Item) queue.elementAt(index)).getElement();
       }
       return null;
   }

    public int getPriority(int index) {
       if (index < size()) {
            return ((Item) queue.elementAt(index)).getPriority();
       }
       return -1;
   }

   public boolean isEmpty() {
       return queue.isEmpty();
   }

   public Object first() {
       if (queue.isEmpty())
           return null;

       return ((Item) queue.firstElement()).getElement();
   }

   public int size() {
       return queue.size();
   }

   public int indexOf(Object element) {
       for(int i = 0; i < queue.size(); i++) {
           Object elementAt = ((Item) queue.elementAt(i)).getElement();
           if (element == elementAt) {
               return i;
           }
       }
       return -1;
   }

   private void insertItemByPriority(Item item) {
       boolean inserted = false;
       int length = queue.size();

       for(int i = 0; i < length; i++) {
           Item indexItem = (Item) queue.elementAt(i);

           if (item.getPriority() < indexItem.getPriority()) {
               if (item.getElement() == indexItem.getElement()) {
                   return;
               }
               queue.insertElementAt(item, i);
               inserted = true;
               break;
           }
       }

       // Queue is Empty or ItemPriority Greater than all of other items
       if (!inserted) {
           queue.addElement(item);
       }
   }



   private class Item {
       int priority; Object element;

       public Item(Object element, int priority) {
           this.priority = priority;
           this.element = element;
       }

       public int getPriority() {
           return priority;
       }

       public Object getElement() {
           return element;
       }
   }

}
